<template>
  <div id="add_picture_page">
    <h2 style="margin-bottom: 16px">{{ route.query.id ? '修改图片' : '新增图片' }}</h2>
    <a-typography-paragraph v-if="spaceId" type="secondary">
      保存至空间：<a :href="`/space/${spaceId}`" target="_blank">{{ spaceId }}</a>
    </a-typography-paragraph>
    <a-tabs v-model:activeKey="uploadType">
      <a-tab-pane key="file" tab="文件上传">
        <picture-upload :picture="picture" :space-id="spaceId" :onSuccess="onSuccess" />
      </a-tab-pane>
      <a-tab-pane key="url" tab="URL 上传" force-render>
        <url-picture-upload :picture="picture" :space-id="spaceId" :onSuccess="onSuccess" />
      </a-tab-pane>
    </a-tabs>
    <div style="margin-bottom: 16px;"></div>
    <div class="function-bar" style="text-align: center;margin-bottom: 16px;">
      <a-space   v-if="picture?.url" size="middle">
        <a-button :icon="h(EditOutlined)" @click="doEditPicture">编辑图片</a-button>
        <a-button type="primary" ghost :icon="h(FullscreenOutlined)" @click="doImageOutPainting"
        >AI扩图
        </a-button>
      </a-space>
    </div>

    <a-form
      layout="vertical"
      :model="pictureForm"
      name="basic"
      autocomplete="off"
      @finish="handleSubmit"
    >
      <a-form-item label="名称" name="name">
        <a-input v-model:value="pictureForm.name" placeholder="请输入名称" />
      </a-form-item>

      <a-form-item label="简介" name="introduction">
        <a-textarea
          v-model:value="pictureForm.introduction"
          placeholder="请输入简介"
          :auto-size="{ minRows: 1, maxRows: 5 }"
          allowClear
        />
      </a-form-item>
      <a-form-item label="分类" name="category">
        <a-auto-complete
          v-model:value="pictureForm.category"
          :options="categoryOptions"
          placeholder="请输入分类"
          allowClear
        />
      </a-form-item>
      <a-form-item label="标签" name="tags">
        <a-select
          v-model:value="pictureForm.tags"
          mode="tags"
          style="width: 100%"
          placeholder="请输入标签"
          :options="tagsOptions"
          allowClear
        ></a-select>
      </a-form-item>

      <a-form-item>
        <a-button type="primary" style="width: 100%" html-type="submit">创建</a-button>
      </a-form-item>
    </a-form>
    <!--  编辑图片组件  -->
    <image-cropper
      ref="imageCropperRef"
      :image-url="picture?.url"
      :picture="picture"
      :space-id="spaceId"
      :space="space"
      :on-success="onCropperSuccess"
    />
    <!--  AI扩图组件  -->
    <image-out-painting
      ref="imageOutPaintingRef"
      :picture="picture"
      :on-success="onImageOutPaintingSuccess"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed, h, watchEffect } from 'vue'
import { message } from 'ant-design-vue'
import { useRoute, useRouter } from 'vue-router'

import {
  editPictureUsingPost,
  getPictureVoByIdUsingGet,
  listPictureTagCategoryUsingGet,
} from '@/request/api/pictureController.ts'
import UrlPictureUpload from '@/components/UrlPictureUpload.vue'
import PictureUpload from '@/components/PictureUpload.vue'
import { EditOutlined, FullscreenOutlined } from '@ant-design/icons-vue'
import ImageCropper from '@/components/ImageCropper.vue'
import ImageOutPainting from '@/components/ImageOutPainting.vue'
import { getSpaceVoByIdUsingGet } from '@/request/api/spaceController.ts'

const router = useRouter()
const route = useRoute()
// 控制上传方式，并且只能是file或者是url类型
const uploadType = ref<'file' | 'url'>('file')
// 图片信息
const picture = ref<API.PictureVO>({})
// 表单信息
const pictureForm = reactive<API.PictureEditRequest>({})
const spaceId = computed(() => route.query?.spaceId)

interface OptionsType {
  value?: string
  label?: string
}

const categoryOptions = ref<Array<OptionsType>>([])
const tagsOptions = ref<Array<OptionsType>>([])

const onSuccess = (newPicture: API.PictureVO) => {
  picture.value = newPicture
  pictureForm.name = newPicture.name
}
// 获取标签和分类选项
const getCategoryTagsOptions = async () => {
  const { data: res } = await listPictureTagCategoryUsingGet()
  if (res.code === 0 && res.data) {
    // 转换下拉框接受的形式
    categoryOptions.value = (res.data.categoryList ?? []).map((category: string) => {
      return { value: category, label: category }
    })
    tagsOptions.value = (res.data.tagList ?? []).map((tag: string) => {
      return { value: tag, label: tag }
    })
  }
}
onMounted(() => {
  getCategoryTagsOptions()
})
// 提交表单
const handleSubmit = async (value: API.PictureEditRequest) => {
  const pictureId = picture.value.id
  if (!pictureId) return
  const { data: res } = await editPictureUsingPost({
    id: pictureId,
    spaceId: spaceId.value,
    ...value,
  })
  if (res.code === 0 && res.data) {
    // 提交成功
    message.success('创建成功')
    // 跳转到图片详情
    router.push({
      path: `/picture/${pictureId}`,
    })
  } else {
    // 提交失败
    message.error('创建失败' + res.message)
  }
}

// 如果是修改图片，获取图片信息
const getPictureInfo = async () => {
  const pictureId = route.query.id as string
  if (!pictureId) return
  const { data: res } = await getPictureVoByIdUsingGet({
    id: pictureId,
  })
  if (res.code === 0 && res.data) {
    picture.value = res.data
    // 直接将整个赋值的话丢失响应式
    pictureForm.name = res.data.name
    pictureForm.introduction = res.data.introduction
    pictureForm.category = res.data.category
    pictureForm.tags = res.data.tags
  }
}

const imageCropperRef = ref<InstanceType<typeof ImageCropper>>()
// 编辑图片
const doEditPicture = () => {
  if (imageCropperRef.value) {
    imageCropperRef.value.openModal()
  }
}
// 图片裁剪成功回调
const onCropperSuccess = (newPicture: API.PictureVO) => {
  picture.value = newPicture

}

const imageOutPaintingRef = ref<InstanceType<typeof ImageOutPainting>>()
// 打开AI扩图弹框
const doImageOutPainting = () => {
  if (imageOutPaintingRef.value) {
    imageOutPaintingRef.value.openModal()
  }
}
// 图片扩图成功回调
const onImageOutPaintingSuccess = (newPicture: API.PictureVO) => {
  picture.value = newPicture
}

const space = ref<API.SpaceVO>()
const fetchSpace = async () => {
  if (spaceId.value) {
    const { data: res } = await getSpaceVoByIdUsingGet({ id: spaceId.value })
    if (res.code == 0 && res.data) {
      space.value = res.data
    }
  }
}

watchEffect(()=> {
  fetchSpace()
})

onMounted(() => {
  getPictureInfo()
})
</script>
<style lang="less" scoped>
#add_picture_page {
  max-width: 720px;
  margin: 0 auto;
}
</style>
